#include <std.h>
#include <pio.h>
#include <system.h>
#include <error.h>
#include <dint.h>

//		0		1		2		3		4		5		6		7		8		9		a		b		c		d		e		f
char *pt[]={ \
/*0*/ "Empty","FAT12","XENIX","XENIX","FAT16","DOSEx","FAT16","NTFS ","AIX	","AIX  ","OS/2B","FAT32","FAT32","		","FAT16","W95ex", \
/*1*/ "OPUS ","fat12","Compq","		","FAT16","		","FAT16","NTFS ","AST  ","		","		","		","		","		","		","		", \
/*2*/ "		","		","		","		","NEC  ","		","		","		","		","		","		","		","		","		","		","		", \
/*3*/ "		","		","		","		","		","		","		","		","		","		","		","		","pmagr","		","		","		", \
/*4*/ "VENIX","LINUX","SFS  ","Linux","		","		","		","		","		","		","		","		","		","		","		","		", \
/*5*/ "DM   ","DM6  ","CP/M ","DM6  ","DM6  ","EZ-dr","Goldb","		","		","		","		","		","Priam","		","		","		", \
/*6*/ "		","Speed","		","GNUhu","Novel","Novel","		","		","		","		","		","		","		","		","		","		", \
/*7*/ "DiskS","		","		","		","		","PC/IX","		","QNX4.","QNX4.","QNX4.","		","		","		","		","		","		", \
/*8*/ "MINIX","MINIX","LINUX","LINUX","OS/2 ","LINUX","NTFSv","NTFSv","		","		","		","		","		","		","		","		", \
/*9*/ "		","		","		","Amoeb","Amoeb","		","		","		","		","		","		","		","		","		","		","		", \
/*a*/ "IBMth","		","		","		","		","BSD  ","		","NextS","		","		","		","		","		","		","		","		", \
/*b*/ "		","		","		","		","		","		","		","BSDI ","BSDI ","		","		","		","		","		","		","		", \
/*c*/ "		","DRDOS","		","		","DRDOS","		","DRDOS","Syrin","		","		","		","		","		","		","		","		", \
/*d*/ "		","		","		","		","		","		","		","		","		","		","		","CP/M ","		","		","		","		", \
/*e*/ "		","DOS  ","		","DOS  ","Speed","		","		","		","		","		","		","		","		","		","		","		", \
/*f*/ "		","Speed","DOS3.","		","Speed","		","		","		","		","		","		","		","		","		","Speed","Xenix"};


	
// Disk format -- partition table management code

#define POFF1 0x1be
#define POFF2 0x1ce
#define POFF3 0x1de
#define POFF4 0x1fe

struct pentry	{
	u8 boot;
	u8 bhead;
	u8 bsecthcyl;
	u8 blcyl;
	u8 sys;
	u8 ehead;
	u8 esecthcyl;
	u8 elcyl;
	u32 preceding_sectors;
	u32 nsect;
}__attribute__ ((packed))part1,part2,part3,part4,*part;


#define P_BOOT 0x80
#define P_VALID 0x0

#define getsect(ps) ((ps->bsecthcyl)&0x4f)
#define getcyl(ps) (ps->blcyl+((ps->bsecthcyl >> 6) << 8))

#define getesect(ps) ((ps->esecthcyl)&0x4f)
#define getecyl(ps) (ps->elcyl+((ps->esecthcyl >> 6) << 8))


int read_table()
{
	u8 *buf;
	printdev("\nReading partition table...");
	buf=(u8 *)get_mem(512);
	read_drive(buf,0,1);
	part=(struct pentry *)(buf+POFF1);
	copy(&part1,part,struct pentry);
	part=(struct pentry *)(buf+POFF2);
	copy(&part2,part,struct pentry);
	part=(struct pentry *)(buf+POFF3);
	copy(&part3,part,struct pentry);
	part=(struct pentry *)(buf+POFF4);
	copy(&part4,part,struct pentry);
	printdev("\nPartition-1:%s",pt[part1.sys]);
	printdev("\nPartition-2:%s",pt[part2.sys]);
	printdev("\nPartition-3:%s",pt[part3.sys]);
	printdev("\nPartition-4:%s",pt[part4.sys]);
	free(buf);
	return NULL;
}

u32 find_primary_type_sector(u32 type)
{
	if(part1.sys==type)
		return part1.preceding_sectors;
	else if(part2.sys==type)
		return part2.preceding_sectors;
	else if(part3.sys==type)
		return part3.preceding_sectors;
	else if(part4.sys==type)
		return part4.preceding_sectors;
	return NULL;
}



kdrv ptman={
	.name="partitionman",
	.init=read_table,
	.reset=NULL,
	.deinit=NULL,
	.select_subdevice=NULL,
	.read_char=find_primary_type_sector,
	.read_block=NULL,
	.write_char=NULL,
	.write_block=NULL,
};
